package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.attendance.dto.DepartmentOrUserSimpleDTO;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.system.dto.SysDepartmentDTO;
import com.nineclock.system.mapper.SysCompanyUserMapper;
import com.nineclock.system.mapper.SysDepartmentMapper;
import com.nineclock.system.pojo.SysCompanyUser;
import com.nineclock.system.pojo.SysDepartment;
import com.nineclock.system.service.SysDepartmentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 * @Version 1.0
 */
@Service
@Slf4j
public class SysDepartmentServiceImpl implements SysDepartmentService {

    @Autowired
    SysDepartmentMapper departmentMapper;

    @Override
    public List<SysDepartmentDTO> queryDepartmentList() {

        List<SysDepartmentDTO> departmentDTOList = queryChildrenDepartmentList(0L);

        return departmentDTOList;
    }

    @Override
    public List<Long> queryTopDepartmentIds() {

        LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        wrapper.eq(SysDepartment::getParentId, 0); //顶级部门

        List<SysDepartment> departmentList = departmentMapper.selectList(wrapper);
        if(CollectionUtil.isNotEmpty(departmentList)){
            List<Long> ids = departmentList.stream().map(department -> {
                return department.getId();
            }).collect(Collectors.toList());
            return ids;
        }
        return new ArrayList<>();
    }

    @Override
    public List<DepartmentOrUserSimpleDTO> querySimpleDepartment(Long departmentId, Integer includeMember) {
        List<DepartmentOrUserSimpleDTO> all = new ArrayList<>();

        // 查询departmentId 子部门
        LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDepartment::getParentId, departmentId);
        wrapper.eq(SysDepartment::getCompanyId,CurrentUserHolder.get().getCompanyId());
        List<SysDepartment> departmentList = departmentMapper.selectList(wrapper);
        //把 部门列表转换为 返回值类型列表
        List<DepartmentOrUserSimpleDTO> departmentSimpleList = departmentList.stream().map(department -> {
            DepartmentOrUserSimpleDTO departmentSimpleDTO = new DepartmentOrUserSimpleDTO();
            departmentSimpleDTO.setType(1);
            departmentSimpleDTO.setId(department.getId());
            departmentSimpleDTO.setName(department.getName());
            return departmentSimpleDTO;
        }).collect(Collectors.toList());

        all.addAll(departmentSimpleList);

        //如果 includeMember为0 ，说明包含员工信息
        if( includeMember == 0){
            LambdaQueryWrapper<SysCompanyUser> companyUserQw = new LambdaQueryWrapper<>();
            companyUserQw.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
            companyUserQw.eq(SysCompanyUser::getDepartmentId, departmentId);
            List<SysCompanyUser> companyUserList = companyUserMapper.selectList(companyUserQw);

            List<DepartmentOrUserSimpleDTO> userSimpleDTOList = companyUserList.stream().map(companyUser -> {
                DepartmentOrUserSimpleDTO userSimpleDTO = new DepartmentOrUserSimpleDTO();
                userSimpleDTO.setType(2);
                userSimpleDTO.setName(companyUser.getUserName());
                userSimpleDTO.setId(companyUser.getId());
                return userSimpleDTO;
            }).collect(Collectors.toList());

            all.addAll(userSimpleDTOList);
        }

        return all;
    }

    /**
     * 查询员工所在的部门id， 包含部门的上级部门id， 上级的上级部门id  ......
     * @param companyUserId
     * @return
     */
    @Override
    public List<Long> queryDepartmentsByUserId(Long companyUserId) {
        List<Long> ids = new ArrayList<>();

        if(companyUserId == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //根据员工id 查询员工信息
        SysCompanyUser companyUser = companyUserMapper.selectById(companyUserId);
        if(companyUser == null){
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }

        //获取员工所在的部门
        Long departmentId = companyUser.getDepartmentId();
        ids.add(departmentId);
        // 获取部门所在的上级部门id
        while (true){
            //根据部门id查询部门信息
            SysDepartment department = departmentMapper.selectById(departmentId);
            //获取部门的上级部门id
            Long parentId = department.getParentId();
            //如果查询到顶级部门，则退出
            if(parentId == 0){
                break;
            }
            //上级部门id添加到集合中
            ids.add(parentId);
            //为下一次循环做准备， 根据上级部门id查询上级部门
            departmentId = parentId;
        }

        return ids;
    }

    @Autowired
    SysCompanyUserMapper companyUserMapper;

    public List<SysDepartmentDTO> queryChildrenDepartmentList(Long parentId){
        //先查询 子部门
        LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDepartment::getParentId, parentId);
        wrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        //包含所有的 子部门
        List<SysDepartment> departmentList = departmentMapper.selectList(wrapper);
        if(CollectionUtil.isNotEmpty(departmentList)){
            List<SysDepartmentDTO> departmentDTOList = BeanHelper.copyWithCollection(departmentList, SysDepartmentDTO.class);
            //遍历 查询子部门的 子部门
            for (SysDepartmentDTO departmentDTO : departmentDTOList) {
                //获取 子部门的子部门列表
                List<SysDepartmentDTO> childDepartmentDTOList = this.queryChildrenDepartmentList(departmentDTO.getId());
                departmentDTO.setChildren(childDepartmentDTOList);
            }
            return departmentDTOList;
        }
        return new ArrayList<>();
    }
}
